package com.omt.tarjimdinek.domain.user.Service;

import static org.apache.commons.lang.StringUtils.isNotEmpty;

import java.util.ArrayList;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Singleton;

import org.apache.log4j.Logger;
import org.springframework.transaction.annotation.Transactional;

import com.omt.tarjimdinek.domain.member.entity.Adresse;
import com.omt.tarjimdinek.domain.member.entity.Membre;
import com.omt.tarjimdinek.domain.member.service.AdresseRepository;
import com.omt.tarjimdinek.domain.member.service.MembreRepository;
import com.omt.tarjimdinek.domain.user.dao.UtilisateurCriteria;
import com.omt.tarjimdinek.domain.user.dao.UtilisateurDao;
import com.omt.tarjimdinek.domain.user.entity.Role;
import com.omt.tarjimdinek.domain.user.entity.Utilisateur;
import com.omt.tarjimdinek.support.GenericDao;
import com.omt.tarjimdinek.support.RepositoryImpl;
import com.omt.tarjimdinek.web.home.SubscriptionCriteria;

/**
 * Default implementation of the {@link UtilisateurRepository} interface.
 * Note: you may use multiple DAO from this layer.
 * @see utilisateurRepository
 */
@Named("accountRepository")
@Singleton
public class UtilisateurRepositoryImpl extends RepositoryImpl<Utilisateur, Long> implements UtilisateurRepository {

    @SuppressWarnings("unused")
    private static final Logger log = Logger.getLogger(UtilisateurRepositoryImpl.class);

    protected UtilisateurDao accountDao;

    protected MembreRepository membreRepository;
    
    protected AdresseRepository adresseRepository;
    
    protected RoleRepository roleRepository;
    
    /**
     * Dao getter used by the {@link RepositoryImpl}.
     */
    @Override
    public GenericDao<Utilisateur, Long> getDao() {
        return accountDao;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Utilisateur getNew() {
        return new Utilisateur();
    }

    /**
     * {@inheritDoc}
     */
    @Override
    public Utilisateur getNewWithDefaults() {
    	Utilisateur result = getNew();
        result.initDefaultValues();
        return result;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = true)
    public Utilisateur get(Utilisateur model) {
        if (model == null) {
            return null;
        }

        if (model.isIdSet()) {
            return super.get(model);
        }

        if (!isNotEmpty(model.getLogin())) {
        	Utilisateur result = getByUsername(model.getLogin());
            if (result != null) {
                return result;
            }
        }

        if (!isNotEmpty(model.getLogin())) {
        	Utilisateur result = getByEmail(model.getLogin());
            if (result != null) {
                return result;
            }
        }

        return null;
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = true)
    public Utilisateur getByUsername(String _username) {
    	Utilisateur account = new Utilisateur();
        account.setLogin(_username);
        return findUniqueOrNone(account);
    }
    
    

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional
    public void deleteByUsername(String username) {
        delete(getByUsername(username));
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional(readOnly = true)
    public Utilisateur getByEmail(String _email) {
    	Utilisateur account = new Utilisateur();
        account.setLogin(_email);
        return findUniqueOrNone(account);
    }

    /**
     * {@inheritDoc}
     */
    @Override
    @Transactional
    public void deleteByEmail(String email) {
        delete(getByEmail(email));
    }

	@Override
	public Utilisateur getUtilisateurByUserName(String aUserName) {
		
		UtilisateurCriteria lCriteria = new UtilisateurCriteria();
		lCriteria.setUserName(aUserName);
		return accountDao.findUtilisateurByCriteria(lCriteria);
	}

	@Override
	@Transactional
	public Utilisateur createNewUtilisateur(SubscriptionCriteria aCriteria) {
		
		Utilisateur lUtilisateur = getNew();
		lUtilisateur.setLogin(aCriteria.getEmail2());
		lUtilisateur.setPassword(aCriteria.getMotDePasse2());
		
		Membre lMembre = new Membre();
		lMembre.setEmail(aCriteria.getEmail2());
		lMembre.setPrenom(aCriteria.getPrenom());
		lMembre.setDateNaissance(aCriteria.getDateDeNaissance());
		
		// Create an address
		Adresse lAdresse = new Adresse();
		lAdresse.setPays(aCriteria.getPays());
		adresseRepository.create(lAdresse);
		
		// Create a member
		lMembre.setAdresse(lAdresse);
		membreRepository.create(lMembre);
			
		// Create a user
		lUtilisateur.setMembre(lMembre);
		lUtilisateur.setEnabled(Boolean.FALSE);
		save(lUtilisateur);
		
		// Create a default role
		lUtilisateur.setListeRoles(new ArrayList<Role>());
		Role lRoleMembre = new Role();
		lRoleMembre.setLibelle(Role.ROLE_MEMBRE);
		lRoleMembre.setUtilisateur(lUtilisateur);
		roleRepository.create(lRoleMembre);
		lUtilisateur.getListeRoles().add(lRoleMembre);
		
		return lUtilisateur;
	}
	
    @Inject
    public void setUtilisateurDao(UtilisateurDao accountDao) {
        this.accountDao = accountDao;
    }
    
    @Inject
    public void setMembreRepository(MembreRepository membreRepository) {
        this.membreRepository = membreRepository;
    }
    
    @Inject
    public void setAdresseRepository(AdresseRepository adresseRepository) {
        this.adresseRepository = adresseRepository;
    }

    @Inject
	public void setRoleRepository(RoleRepository roleRepository) {
		this.roleRepository = roleRepository;
	}
}